/**
 * Create in 2012-10-12 下午10:45:09.
 */
package kit4j.app.notepad.factory;

import java.awt.Font;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import kit4j.app.notepad.config.NotepadConfig;
import kit4j.app.notepad.factory.listener.NotepadFactoryListener;
import kit4j.app.notepad.ui.window.Notepad;

import com.google.inject.Inject;

/**
 * 
 * @author MiniKnife
 * 
 */
public class NotepadFactory {

	private static NotepadFactory instance;

	private NotepadConfig config;

	private List<Notepad> freeNotepadList;

	private List<Notepad> showingNotepadList;

	private Set<NotepadFactoryListener> listenerSet;

	@Inject
	public NotepadFactory(NotepadConfig config) {
		this.config = config;
		freeNotepadList = new ArrayList<Notepad>();
		showingNotepadList = new ArrayList<Notepad>();
		listenerSet = new HashSet<NotepadFactoryListener>();
	}

	public static NotepadFactory getInstance() {
		return instance;
	}

	@Inject
	public static void setNotepadFactoryInstance(NotepadFactory factory) {
		instance = factory;
	}

	public void addNotepadFactoryListener(NotepadFactoryListener l) {
		listenerSet.add(l);
	}

	public void removeNotepadFactoryListener(NotepadFactoryListener l) {
		listenerSet.remove(l);
	}

	public Notepad showNewNotepad() {
		Notepad newPad = createNotepad();

		newPad.setVisible(true);
		showingNotepadList.add(newPad);
		notepadShowed(newPad);

		return newPad;
	}

	protected void notepadShowed(Notepad notepad) {
		for (NotepadFactoryListener l : listenerSet) {
			l.notepadShowed(notepad);
		}
	}

	protected void notepadFreed(Notepad notepad) {
		for (NotepadFactoryListener l : listenerSet) {
			l.notepadFreed(notepad);
		}
	}

	private Notepad createNotepad() {
		Notepad newPad = null;

		if (freeNotepadList.isEmpty()) {
			newPad = new Notepad(config);
		} else {
			newPad = freeNotepadList.remove(freeNotepadList.size() - 1);
		}

		Integer width = config.getInteger("NOTEPAD.DEFAULT_WIDTH");
		Integer height = config.getInteger("NOTEPAD.DEFAULT_HEIGHT");
		Integer x = config.getInteger("NOTEPAD.DEFAULT_X");
		Integer y = config.getInteger("NOTEPAD.DEFAULT_Y");
		Font font = config.getFont("NOTEPAD.TEXTAREA.DEFAULT_FONT");

		if (width == null || height == null) {
			Font textFont = config.getFont("NOTEPAD.TEXT_FONT");
			int fontSize = 12;

			if (textFont != null) {
				fontSize = textFont.getSize();
			}

			if (width == null) {
				width = fontSize * 2;
			}

			if (height == null) {
				height = fontSize * 2;
			}
		}
		newPad.setSize(width, height);

		if (x != null && y != null) {
			newPad.setLocation(x, y);
		} else {
			newPad.setLocationRelativeTo(null);
		}

		if (font != null) {
			newPad.getTextArea().setFont(font);
		}

		return newPad;
	}

	public void freeNotepad(Notepad notepad) {
		if (showingNotepadList.remove(notepad)) {
			notepad.clean();
			notepad.setVisible(false);
			freeNotepadList.add(notepad);
			notepadFreed(notepad);
		}
	}

	/**
	 * @return the showingNotepadList
	 */
	public List<Notepad> getShowingNotepadList() {
		return new ArrayList<Notepad>(showingNotepadList);
	}
}
